﻿using Acme.BookStore.Ball;
using Acme.BookStore.Car;  // 添加 Vehicle 的引用
using Acme.BookStore.Domain.Entities;
using Acme.BookStore.FormWhx.Storehouse;
using Acme.BookStore.Migrations;
using Acme.BookStore.Products;
using Acme.BookStore.Purchase.Customergoods;
using Acme.BookStore.Purchase.NotificationOrder;
using Acme.BookStore.Purchase.Otherwarehousing;
using Acme.BookStore.Purchase.ReceiptOrder;
using Acme.BookStore.Shops;
using Microsoft.EntityFrameworkCore;
using Volo.Abp.AuditLogging.EntityFrameworkCore;
using Volo.Abp.BackgroundJobs.EntityFrameworkCore;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore.Modeling;
using Volo.Abp.FeatureManagement.EntityFrameworkCore;
using Volo.Abp.Identity;
using Volo.Abp.Identity.EntityFrameworkCore;
using Volo.Abp.OpenIddict.EntityFrameworkCore;
using Volo.Abp.PermissionManagement.EntityFrameworkCore;
using Volo.Abp.SettingManagement.EntityFrameworkCore;
using Volo.Abp.TenantManagement;
using Volo.Abp.TenantManagement.EntityFrameworkCore;
using Acme.BookStore.Products;
using Acme.BookStore.Shops;
using Acme.BookStore.FormWhx.Binlocation;
using Acme.BookStore.FormWhx.Ruku;

namespace Acme.BookStore.EntityFrameworkCore;

[ReplaceDbContext(typeof(IIdentityDbContext))]
[ReplaceDbContext(typeof(ITenantManagementDbContext))]
[ConnectionStringName("Default")]
public class BookStoreDbContext :
    AbpDbContext<BookStoreDbContext>,
    IIdentityDbContext,
    ITenantManagementDbContext
{
    /* Add DbSet properties for your Aggregate Roots / Entities here. */
    public DbSet<Shop> Shops { get; set; }
    public DbSet<GoodsModel> GoodsModels { get; set; }
    public DbSet<BallModel> Balls { get; set; }
    public DbSet<CustomergoodsModel> Customergoods { get; set; }
    public DbSet<Book> Books { get; set; }
    public DbSet<Kehu> Kehus { get; set; }
    public DbSet<Rfid> Rfids { get; set; }
    public DbSet<ShopWhere> ShopWheres { get; set; }
    public DbSet<Vehicle> Vehicles { get; set; }
    public DbSet<ADManagement> ADManagements { get; set; }
    public DbSet<Orders> Orders { get; set; }
    public DbSet<ManagementDeptModel> ManagementDeptModels { get; set; }
    public DbSet<SorehouseModels> SorehouseModels { get; set; }
    public DbSet<WarehouseManagerModel> WarehouseManagerModels { get; set; }
    public DbSet<OtherwarehousingModel> OtherwarehousingModels { get; set; }
    public DbSet<WarehouseOperationLog> WarehouseOperationLogs { get; set; }
    // public DbSet<InventoryTransfer> InventoryTransfer { get; set; }
    public DbSet<InventryTran> InventryTrans { get; set; }
    public DbSet<NotificationOrders> NotificationOrders { get; set; }
    public DbSet<ReceiptOrders> ReceiptOrders { get; set; }
    public DbSet<Gongying> Gongyings { get; set; }
    
    // 新增库存管理相关的DbSet
    public DbSet<Car.CarInventryss> CarInventryss { get; set; }
    public DbSet<Merchandise> Merchandise { get; set; }
    public DbSet<Goods> Goods { get; set; }
    public DbSet<locationModel> locationModels { get; set; }
    public DbSet<OrderOutStock> OrderOutStock { get; set; }
    public DbSet<OrderOutDetail> OrderOutDetail { get; set; }
    public DbSet<CarFleetsc> CarFleetsc { get; set; }
    public DbSet<ItemsModel> ItemsModels { get; set; }
    public DbSet<RuKuModel> RukuModels { get; set; }
    public DbSet<RuKuDetailModel> RuKuDetailModels { get; set; }
    public DbSet<ConnectFromModel> ConnectFromModels { get; set; }

    #region Entities from the modules

    /* Notice: We only implemented IIdentityDbContext and ITenantManagementDbContext
     * and replaced them for this DbContext. This allows you to perform JOIN
     * queries for the entities of these modules over the repositories easily. You
     * typically don't need that for other modules. But, if you need, you can
     * implement the DbContext interface of the needed module and use ReplaceDbContext
     * attribute just like IIdentityDbContext and ITenantManagementDbContext.
     *
     * More info: Replacing a DbContext of a module ensures that the related module
     * uses this DbContext on runtime. Otherwise, it will use its own DbContext class.
     */

    //Identity
    public DbSet<IdentityUser> Users { get; set; }
    public DbSet<IdentityRole> Roles { get; set; }
    public DbSet<IdentityClaimType> ClaimTypes { get; set; }
    public DbSet<OrganizationUnit> OrganizationUnits { get; set; }
    public DbSet<IdentitySecurityLog> SecurityLogs { get; set; }
    public DbSet<IdentityLinkUser> LinkUsers { get; set; }
    public DbSet<IdentityUserDelegation> UserDelegations { get; set; }
    public DbSet<IdentitySession> Sessions { get; set; }
    
    // Tenant Management
    public DbSet<Tenant> Tenants { get; set; }
    public DbSet<TenantConnectionString> TenantConnectionStrings { get; set; }

    #endregion

    public BookStoreDbContext(DbContextOptions<BookStoreDbContext> options)
        : base(options)
    {

    }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);

        builder.Entity<CustomergoodsModel>(x =>
        {
            x.ToTable(BookStoreConsts.DbTablePrefix + "Customergoods",
               BookStoreConsts.DbSchema);
        });

        builder.Entity<BallModel>(b =>
        {
            b.ToTable(BookStoreConsts.DbTablePrefix + "Balls",
                BookStoreConsts.DbSchema);

            b.ConfigureByConvention();

            b.Property(x => x.Name)
                .IsRequired()
                .HasMaxLength(100);

            b.Property(x => x.Type)
                .IsRequired();

            b.Property(x => x.Price)
                .IsRequired()
                .HasColumnType("decimal(18,2)");

            b.Property(x => x.Brand)
                .IsRequired();

            b.Property(x => x.Hobby)
                .HasMaxLength(500);
        });

        /* Include modules to your migration db context */

        builder.ConfigurePermissionManagement();
        builder.ConfigureSettingManagement();
        builder.ConfigureBackgroundJobs();
        builder.ConfigureAuditLogging();
        builder.ConfigureIdentity();
        builder.ConfigureOpenIddict();
        builder.ConfigureFeatureManagement();
        builder.ConfigureTenantManagement();
        
        // 添加这一行，应用自定义实体配置
        builder.ConfigureBookStore();

        /* Configure your own tables/entities inside here */

        //builder.Entity<YourEntity>(b =>
        //{
        //    b.ToTable(BookStoreConsts.DbTablePrefix + "YourEntities", BookStoreConsts.DbSchema);
        //    b.ConfigureByConvention(); //auto configure for the base class props
        //    //...
        //});

        // 添加 Vehicle 实体的配置
        builder.Entity<Vehicle>(b =>
        {
            b.ToTable(BookStoreConsts.DbTablePrefix + "Vehicles", BookStoreConsts.DbSchema);
            b.ConfigureByConvention(); // 配置基类属性

            // 配置 Vehicle 的属性
            b.Property(x => x.VehicleNumber)
                .IsRequired()
                .HasMaxLength(200);

            b.Property(x => x.VehicleModel)
                .IsRequired()
                .HasMaxLength(200);

            b.Property(x => x.MaximumVolume)
                .IsRequired();

            b.Property(x => x.LoadCapacity)
                .IsRequired()
                .HasPrecision(18, 2);

            b.Property(x => x.Passengers)
                .IsRequired();

            b.Property(x => x.Qualified)
                .HasMaxLength(50);

            b.Property(x => x.VehicleName)
                .IsRequired()
                .HasMaxLength(200);

            b.Property(x => x.Phone)
                .HasMaxLength(20);

            b.Property(x => x.DefaultDriver)
                .HasMaxLength(200);

            b.Property(x => x.LicenseNumber)
                .IsRequired()
                .HasMaxLength(50);

            b.Property(x => x.Region)
                .HasMaxLength(200);
        });

        builder.Entity<ADManagement>(b =>
        {
            b.ToTable(BookStoreConsts.DbTablePrefix + "ADManagements", BookStoreConsts.DbSchema);
            b.ConfigureByConvention();

            b.Property(x => x.ADManagementUser).IsRequired().HasMaxLength(100);
            b.Property(x => x.ADManagementPerson).IsRequired().HasMaxLength(50);
            b.Property(x => x.ADManagementPhone).IsRequired().HasMaxLength(20);
            b.Property(x => x.DetailedAddress).IsRequired().HasMaxLength(200);
            b.Property(x => x.Province).IsRequired().HasMaxLength(50);
            b.Property(x => x.ADManagementCity).IsRequired().HasMaxLength(50);
            b.Property(x => x.ADManagementDistrict).IsRequired().HasMaxLength(50);
            b.Property(x => x.DefaultAddress).HasMaxLength(10);
            b.Property(x => x.Available).HasMaxLength(10);
            b.Property(x => x.DetailedAddressType).HasMaxLength(50);
        });

        // 添加 Orders 实体的配置
        builder.Entity<Orders>(b =>
        {
            b.ToTable(BookStoreConsts.DbTablePrefix + "Orders", BookStoreConsts.DbSchema);
            b.ConfigureByConvention(); // 配置基类属性
        });
        
        // 添加 Book 实体的配置
        builder.Entity<Book>(b =>
        {
            b.ToTable(BookStoreConsts.DbTablePrefix + "Books", BookStoreConsts.DbSchema);
            b.ConfigureByConvention();

            b.Property(x => x.Name).IsRequired().HasMaxLength(128);
        });

    }
}
